//! 事务系统增强测试
//! 
//! 本模块包含对事务系统Week 7-8增强功能的测试

use super::transaction::*;
use super::page::PageManager;
use super::tuple::RowId;
use std::sync::Arc;
use std::thread;
use std::time::{Duration, Instant};
use tempfile::tempdir;

/// 事务系统增强测试套件
pub struct TransactionEnhancedTestSuite {
    transaction_manager: Arc<TransactionManager>,
    temp_dir: tempfile::TempDir,
}

impl TransactionEnhancedTestSuite {
    /// 创建新的增强测试套件
    pub fn new() -> Result<Self, crate::Error> {
        let temp_dir = tempdir().map_err(|e| crate::Error::storage(format!("创建临时目录失败: {}", e)))?;
        let wal_path = temp_dir.path().join("enhanced_test.wal").to_string_lossy().to_string();
        let page_manager = Arc::new(PageManager::new(1000));
        
        let transaction_manager = Arc::new(TransactionManager::new(page_manager, wal_path)?);
        
        Ok(Self {
            transaction_manager,
            temp_dir,
        })
    }
    
    /// 测试ACID原子性
    pub fn test_acid_atomicity(&self) -> Result<(), crate::Error> {
        println!("🧪 测试ACID原子性...");
        
        // 测试正常提交
        let tx1 = self.transaction_manager.begin_transaction(IsolationLevel::ReadCommitted, false)?;
        let mut write_set = tx1.write_set.write();
        write_set.insert(RowId { page_id: 1, slot_id: 1 });
        write_set.insert(RowId { page_id: 1, slot_id: 2 });
        drop(write_set);
        self.transaction_manager.commit_transaction(tx1)?;
        
        // 测试回滚
        let tx2 = self.transaction_manager.begin_transaction(IsolationLevel::ReadCommitted, false)?;
        let mut write_set = tx2.write_set.write();
        write_set.insert(RowId { page_id: 1, slot_id: 3 });
        write_set.insert(RowId { page_id: 1, slot_id: 4 });
        drop(write_set);
        self.transaction_manager.rollback_transaction(tx2)?;
        
        let stats = self.transaction_manager.get_stats();
        assert_eq!(stats.committed_transactions, 1);
        assert_eq!(stats.rolled_back_transactions, 1);
        
        println!("✅ ACID原子性测试通过");
        Ok(())
    }
    
    /// 测试ACID一致性
    pub fn test_acid_consistency(&self) -> Result<(), crate::Error> {
        println!("🧪 测试ACID一致性...");
        
        // 模拟银行转账场景
        let tx = self.transaction_manager.begin_transaction(IsolationLevel::ReadCommitted, false)?;
        
        // 模拟业务逻辑验证
        let initial_balance_a = 1000;
        let initial_balance_b = 500;
        let transfer_amount = 200;
        
        let final_balance_a = initial_balance_a - transfer_amount;
        let final_balance_b = initial_balance_b + transfer_amount;
        let total_before = initial_balance_a + initial_balance_b;
        let total_after = final_balance_a + final_balance_b;
        
        // 验证总金额保持不变（一致性约束）
        assert_eq!(total_before, total_after);
        
        // 模拟数据变更
        let mut write_set = tx.write_set.write();
        write_set.insert(RowId { page_id: 2, slot_id: 100 }); // 账户A
        write_set.insert(RowId { page_id: 2, slot_id: 101 }); // 账户B
        drop(write_set);
        
        self.transaction_manager.commit_transaction(tx)?;
        
        println!("✅ ACID一致性测试通过");
        Ok(())
    }
    
    /// 测试ACID隔离性
    pub fn test_acid_isolation(&self) -> Result<(), crate::Error> {
        println!("🧪 测试ACID隔离性...");
        
        // 测试读已提交隔离级别
        let tx1 = self.transaction_manager.begin_transaction(IsolationLevel::ReadCommitted, false)?;
        let tx2 = self.transaction_manager.begin_transaction(IsolationLevel::ReadCommitted, true)?;
        
        // tx1修改数据但未提交
        let mut write_set = tx1.write_set.write();
        write_set.insert(RowId { page_id: 3, slot_id: 200 });
        drop(write_set);
        
        // tx2不应该读到未提交的数据
        // 验证快照时间戳
        assert!(tx2.snapshot_timestamp < tx1.id);
        
        self.transaction_manager.commit_transaction(tx1)?;
        self.transaction_manager.commit_transaction(tx2)?;
        
        println!("✅ ACID隔离性测试通过");
        Ok(())
    }
    
    /// 测试ACID持久性
    pub fn test_acid_durability(&self) -> Result<(), crate::Error> {
        println!("🧪 测试ACID持久性...");
        
        // 创建并提交一个事务
        let tx = self.transaction_manager.begin_transaction(IsolationLevel::ReadCommitted, false)?;
        
        let mut write_set = tx.write_set.write();
        write_set.insert(RowId { page_id: 4, slot_id: 300 });
        write_set.insert(RowId { page_id: 4, slot_id: 301 });
        drop(write_set);
        
        self.transaction_manager.commit_transaction(tx)?;
        
        // 验证事务已持久化（通过统计信息）
        let stats = self.transaction_manager.get_stats();
        assert!(stats.committed_transactions > 0);
        
        println!("✅ ACID持久性测试通过");
        Ok(())
    }
    
    /// 测试高并发事务
    pub fn test_high_concurrency(&self) -> Result<(), crate::Error> {
        println!("🧪 测试高并发事务...");
        
        let num_threads = 4;
        let transactions_per_thread = 50;
        let tx_manager = self.transaction_manager.clone();
        
        let start_time = Instant::now();
        
        let handles: Vec<_> = (0..num_threads).map(|thread_id| {
            let tx_manager = tx_manager.clone();
            
            thread::spawn(move || -> Result<(), crate::Error> {
                for i in 0..transactions_per_thread {
                    let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, false)?;
                    
                    let mut write_set = tx.write_set.write();
                    write_set.insert(RowId {
                        page_id: (thread_id + 10) as u64,
                        slot_id: i as u16
                    });
                    drop(write_set);
                    
                    if i % 10 == 0 {
                        tx_manager.rollback_transaction(tx)?;
                    } else {
                        tx_manager.commit_transaction(tx)?;
                    }
                }
                Ok(())
            })
        }).collect();
        
        for handle in handles {
            handle.join().unwrap()?;
        }
        
        let elapsed = start_time.elapsed();
        let total_transactions = num_threads * transactions_per_thread;
        let throughput = total_transactions as f64 / elapsed.as_secs_f64();
        
        println!("  并发事务吞吐量: {:.2} 事务/秒", throughput);
        
        let stats = self.transaction_manager.get_stats();
        assert_eq!(stats.total_transactions, total_transactions as u64);
        
        println!("✅ 高并发事务测试通过");
        Ok(())
    }
    
    /// 测试读写并发
    pub fn test_read_write_concurrency(&self) -> Result<(), crate::Error> {
        println!("🧪 测试读写并发...");
        
        let num_readers = 2;
        let num_writers = 2;
        let operations_per_thread = 25;
        let tx_manager = self.transaction_manager.clone();
        
        let start_time = Instant::now();
        
        // 启动读线程
        let reader_handles: Vec<_> = (0..num_readers).map(|reader_id| {
            let tx_manager = tx_manager.clone();
            
            thread::spawn(move || -> Result<(), crate::Error> {
                for i in 0..operations_per_thread {
                    let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, true)?;
                    
                    let mut read_set = tx.read_set.write();
                    read_set.insert(RowId {
                        page_id: (reader_id + 20) as u64,
                        slot_id: i as u16
                    });
                    drop(read_set);
                    
                    tx_manager.commit_transaction(tx)?;
                }
                Ok(())
            })
        }).collect();
        
        // 启动写线程
        let writer_handles: Vec<_> = (0..num_writers).map(|writer_id| {
            let tx_manager = tx_manager.clone();
            
            thread::spawn(move || -> Result<(), crate::Error> {
                for i in 0..operations_per_thread {
                    let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, false)?;
                    
                    let mut write_set = tx.write_set.write();
                    write_set.insert(RowId {
                        page_id: (writer_id + 30) as u64,
                        slot_id: i as u16
                    });
                    drop(write_set);
                    
                    tx_manager.commit_transaction(tx)?;
                }
                Ok(())
            })
        }).collect();
        
        // 等待所有线程完成
        for handle in reader_handles {
            handle.join().unwrap()?;
        }
        for handle in writer_handles {
            handle.join().unwrap()?;
        }
        
        let elapsed = start_time.elapsed();
        let total_operations = (num_readers + num_writers) * operations_per_thread;
        let throughput = total_operations as f64 / elapsed.as_secs_f64();
        
        println!("  读写并发吞吐量: {:.2} 操作/秒", throughput);
        
        println!("✅ 读写并发测试通过");
        Ok(())
    }
    
    /// 测试事务隔离级别
    pub fn test_isolation_levels(&self) -> Result<(), crate::Error> {
        println!("🧪 测试事务隔离级别...");
        
        let levels = vec![
            IsolationLevel::ReadUncommitted,
            IsolationLevel::ReadCommitted,
            IsolationLevel::RepeatableRead,
            IsolationLevel::Serializable,
        ];
        
        for level in levels {
            let tx = self.transaction_manager.begin_transaction(level, false)?;
            assert_eq!(tx.isolation_level, level);
            
            let mut write_set = tx.write_set.write();
            write_set.insert(RowId { page_id: 40, slot_id: level as u16 });
            drop(write_set);
            
            self.transaction_manager.commit_transaction(tx)?;
        }
        
        let stats = self.transaction_manager.get_stats();
        assert!(stats.committed_transactions >= 4);
        
        println!("✅ 事务隔离级别测试通过");
        Ok(())
    }
    
    /// 运行完整的增强测试套件
    pub fn run_full_enhanced_test_suite(&self) -> Result<(), crate::Error> {
        println!("🚀 开始事务系统增强测试套件...");
        println!("=====================================");
        
        self.test_acid_atomicity()?;
        self.test_acid_consistency()?;
        self.test_acid_isolation()?;
        self.test_acid_durability()?;
        self.test_high_concurrency()?;
        self.test_read_write_concurrency()?;
        self.test_isolation_levels()?;
        
        println!("=====================================");
        println!("🎉 事务系统增强测试套件全部通过！");
        
        let stats = self.transaction_manager.get_stats();
        println!("📊 最终统计:");
        println!("  总事务数: {}", stats.total_transactions);
        println!("  已提交事务: {}", stats.committed_transactions);
        println!("  已回滚事务: {}", stats.rolled_back_transactions);
        println!("  活跃事务: {}", stats.active_transactions);
        
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_enhanced_acid_atomicity() {
        let test_suite = TransactionEnhancedTestSuite::new().unwrap();
        test_suite.test_acid_atomicity().unwrap();
    }
    
    #[test]
    fn test_enhanced_acid_consistency() {
        let test_suite = TransactionEnhancedTestSuite::new().unwrap();
        test_suite.test_acid_consistency().unwrap();
    }
    
    #[test]
    fn test_enhanced_acid_isolation() {
        let test_suite = TransactionEnhancedTestSuite::new().unwrap();
        test_suite.test_acid_isolation().unwrap();
    }
    
    #[test]
    fn test_enhanced_acid_durability() {
        let test_suite = TransactionEnhancedTestSuite::new().unwrap();
        test_suite.test_acid_durability().unwrap();
    }
    
    #[test]
    fn test_enhanced_high_concurrency() {
        let test_suite = TransactionEnhancedTestSuite::new().unwrap();
        test_suite.test_high_concurrency().unwrap();
    }
    
    #[test]
    fn test_enhanced_read_write_concurrency() {
        let test_suite = TransactionEnhancedTestSuite::new().unwrap();
        test_suite.test_read_write_concurrency().unwrap();
    }
    
    #[test]
    fn test_enhanced_isolation_levels() {
        let test_suite = TransactionEnhancedTestSuite::new().unwrap();
        test_suite.test_isolation_levels().unwrap();
    }
    
    #[test]
    fn test_enhanced_full_suite() {
        let test_suite = TransactionEnhancedTestSuite::new().unwrap();
        test_suite.run_full_enhanced_test_suite().unwrap();
    }
}
